package com.tramp.frame.server.interceptor.sql;

import java.sql.Connection;
import java.util.List;
import java.util.Properties;

import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.ibatis.executor.statement.BaseStatementHandler;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.tramp.utils.ClassUtil;

/**
 * sql拦截器(分页)
 *
 * @author chenjm1
 * @since 2017/11/10
 */
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class, Integer.class }) })
public class SqlInterceptor implements Interceptor {
	private static final Logger LOGGER = LoggerFactory.getLogger(SqlInterceptor.class);

	private List<HandlerSQLConverter> sqlConverters;

	@Override
	public Object intercept(Invocation ivk) throws Throwable {
		if (ivk.getTarget() instanceof RoutingStatementHandler) {
			RoutingStatementHandler statementHandler = (RoutingStatementHandler) ivk.getTarget();
			BaseStatementHandler delegate = (BaseStatementHandler) ClassUtil.getValueByFieldName(statementHandler, "delegate");
			MappedStatement mappedStatement = (MappedStatement) ClassUtil.getValueByFieldName(delegate, "mappedStatement");
			BoundSql boundSql = delegate.getBoundSql();
			Connection connection = (Connection) ivk.getArgs()[0];
			//调用applicationContext.xml中配置的HandlerSQLConverter进行SQL转换
			if (CollectionUtils.isNotEmpty(sqlConverters)) {
				for (HandlerSQLConverter sqlConverter : sqlConverters) {
					sqlConverter.convertSql(connection, mappedStatement, boundSql);
				}
			}
		}
		return ivk.proceed();
	}

	public void setSqlConverters(List<HandlerSQLConverter> sqlConverters) {
		this.sqlConverters = sqlConverters;
	}

	@Override
	public Object plugin(Object arg0) {
		return Plugin.wrap(arg0, this);
	}

	@Override
	public void setProperties(Properties properties) {

	}

    public void addSqlConverters(HandlerSQLConverter sqlConverter) {
        if(null == sqlConverters){
            sqlConverters= Lists.newArrayList();
        }
        sqlConverters.add(sqlConverter);
    }
}
